global with sharing class TradeDashboardLastActualBatchClass implements Database.Batchable<sObject>,Database.Stateful {
    Date DToday;
    global Map<String,TradeDashboardDetails__c> LastActualMapList=new Map<String,TradeDashboardDetails__c>();
    
    global TradeDashboardLastActualBatchClass()
    {
        DToday=Date.newInstance(Date.today().year(),Date.today().month(),1);
    }
   
   global Database.QueryLocator start(Database.BatchableContext BC)
   {   string sqlStr;
       if(date.today().day()==2)
       {
            Date LastMonthDate=Date.today().addMonths(-1);//上个月
            Date dt=Date.newInstance(LastMonthDate.year(),LastMonthDate.month(),1);
            String strDate='';
            if(dt.month()<10)
                strDate=String.valueOf(dt.year())+'-0'+String.valueOf(dt.month())+'-'+'01';
            else
                strDate=String.valueOf(dt.year())+'-'+String.valueOf(dt.month())+'-'+'01';
             
             sqlStr='select OwnerId,actual__c,CriticalEnabler__c from TradeDashboardDetails__c where SalesMonth__c='+strDate+' and actual__c>0 and IsActive__c=\'1\'';
        
        //String SqlStr='select OwnerId,count(actual__c)  LastA ,CriticalEnabler__c TypeC,sum(If_Average_product_line__c) avgPL from TradeDashboardDetails__c'+
        //                ' where SalesMonth__c='+strDate+' group by CriticalEnabler__c,ownerid';
        }
        else //if(date.today().day()!=1)
        {
            sqlstr='select id,sku_number__c,LastDistributionDate__c,OwnerId__c,visit_date__c,outletname_del__c,Channel__c,HasRun_TradeDashboardDetails__c from in_store_visit__c where HasRun_TradeDashboardDetails__c=false and IsActive__c=\'1\' order by Visit_Date__c';
        }
        return Database.getQueryLocator(SqlStr); 
   } 
         
   global void execute(Database.BatchableContext BC, List<sObject> scope)
   {
        if(date.today().day()==2)
        {
            String StKey='';
            
            for(SObject obj:scope)
            {
                TradeDashboardDetails__c rs=(TradeDashboardDetails__c)obj;
                StKey=String.valueOf(DToday)+rs.OwnerId+'LastActual'+rs.CriticalEnabler__c;//日期+OwnerId+字符+类型
                if(LastActualMapList.containsKey(StKey))
                {
                    TradeDashboardDetails__c SetActual=LastActualMapList.get(StKey);
                    SetActual.LastMonthActual__c+=rs.actual__c;
                    LastActualMapList.put(StKey,SetActual);
                }
                else
                {
                    TradeDashboardDetails__c SetActual=new TradeDashboardDetails__c();
                    SetActual.CriticalEnabler__c=rs.CriticalEnabler__c;
                    SetActual.OwnerId=rs.OwnerId;
                    SetActual.TSR__c=rs.OwnerId;
                    SetActual.SalesMonth__c=DToday;
                    SetActual.LastMonthActual__c=rs.actual__c;
                    SetActual.PrimaryKeyId__c=StKey;
                    LastActualMapList.put(StKey,SetActual);
                }
            }
            if(LastActualMapList.size()>0)
                upsert LastActualMapList.values() PrimaryKeyId__c;
        }
        else
        {
                    
            //遍历ISV，生成TDD记录
            map<string,tradedashboarddetails__c> upsertTDD=new map<string,tradedashboarddetails__c>();
            map<string,tradedashboarddetails__c> insertTDD=new map<string,tradedashboarddetails__c>();
            map<string,tradedashboarddetails__c> upsertTDDM=new map<string,tradedashboarddetails__c>();
            in_store_visit__c i;
            list<in_store_visit__c> isvUpdate=new list<in_store_visit__c>();
            for(SObject obj:scope){
                i=(in_store_visit__c)obj;
                i.HasRun_TradeDashboardDetails__c=true;
                tradedashboarddetails__c tdd=new tradedashboarddetails__c(
                             criticalEnabler__c='Coverage',actual__c=1,tsr__c=i.OwnerId__c,
                             ownerid=i.OwnerId__c,outlet__c=i.OutletName_del__c,
                             salesmonth__c=i.visit_date__c.tostartofmonth());
                insertTDD.put(i.id,tdd);
                tradedashboarddetails__c CovTar=new tradedashboarddetails__c(
                             criticalEnabler__c='Coverage',ScoreStandard__c=ScoreStandard__c.getValues('Coverage').Standard__c,
                             target__c=(TargetStandard__c.getValues(i.Channel__c).CallFrequencyStandard__c),
                             ownerid=i.OwnerId__c,outlet__c=i.OutletName_del__c,
                             salesmonth__c=i.visit_date__c.tostartofmonth(),PrimaryKeyId__c='Coverage'+i.outletname_del__c+i.visit_date__c.tostartofmonth()+'target');
                upsertTddM.put((string)i.outletname_del__c+i.visit_date__c.tostartofmonth(),CovTar);
                if(i.LastDistributionDate__c!=null){//i.If_in_the_last_visit__c==1 || i.If_in_the_last_visit_This_Month__c==1
                tradedashboarddetails__c tddapl=new tradedashboarddetails__c(
                             criticalEnabler__c='Average product line',ScoreStandard__c=ScoreStandard__c.getValues('Average product line').Standard__c,
                             target__c=TargetStandard__c.getValues(i.Channel__c).SKUStandard__c,actual__c=i.sku_number__c,
                             ownerid=i.OwnerId__c,outlet__c=i.OutletName_del__c,tsr__c=i.OwnerId__c,
                             salesmonth__c=i.visit_date__c.tostartofmonth(),PrimaryKeyId__c='Average product line'+i.OwnerId__c+i.visit_date__c.tostartofmonth()+i.OutletName_del__c
                            );
                 upsertTDD.put(i.id,tddapl);     
               }
               isvupdate.add(i);
            }
            upsert upsertTdd.values() PrimaryKeyId__c; 
            upsert upsertTddm.values() primarykeyid__c;
            insert insertTDD.values();
            upserttdd.clear();
            insertTDD.CLEAR();
            
            update isvupdate;            
        } 
        
   }
   
  
   global void finish(Database.BatchableContext BC){
    
   }
}